import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:record/record.dart';
import '../utils/ui_helper.dart';

// 录音状态
enum RecordingStatus {
  idle,
  recording,
  error,
}

// 每个回调的标识和回调集合
class StatusCallbackEntry {
  final String id;
  final Function(RecordingStatus) callback;

  StatusCallbackEntry(this.id, this.callback);
}

class ErrorCallbackEntry {
  final String id;
  final Function(String) callback;

  ErrorCallbackEntry(this.id, this.callback);
}

class AudioDataCallbackEntry {
  final String id;
  final Function(Uint8List) callback;

  AudioDataCallbackEntry(this.id, this.callback);
}

// 录音服务类
class RecorderService {
  // 单例实现
  static final RecorderService _instance = RecorderService._internal();
  factory RecorderService() => _instance;
  RecorderService._internal();

  // 录音器实例
  final AudioRecorder _audioRecorder = AudioRecorder();

  // 状态变量
  RecordingStatus _status = RecordingStatus.idle;
  RecordingStatus get status => _status;

  // 音频流订阅
  StreamSubscription? _audioStreamSubscription;

  // 回调集合 - 使用列表管理多个回调
  final List<AudioDataCallbackEntry> _audioDataCallbacks = [];
  final List<ErrorCallbackEntry> _errorCallbacks = [];
  final List<StatusCallbackEntry> _statusCallbacks = [];

  // 初始化录音服务，设置回调函数
  void initialize({
    required String callbackId, // 添加回调ID参数，用于识别回调所属的页面
    Function(Uint8List)? onAudioData,
    Function(String)? onError,
    Function(RecordingStatus)? onStatusChanged,
  }) {
    // 先移除该ID之前注册的回调
    removeCallbacks(callbackId);

    // 添加新回调
    if (onAudioData != null) {
      _audioDataCallbacks.add(AudioDataCallbackEntry(callbackId, onAudioData));
    }

    if (onError != null) {
      _errorCallbacks.add(ErrorCallbackEntry(callbackId, onError));
    }

    if (onStatusChanged != null) {
      _statusCallbacks.add(StatusCallbackEntry(callbackId, onStatusChanged));
    }
  }

  // 移除某个ID的所有回调
  void removeCallbacks(String callbackId) {
    _audioDataCallbacks.removeWhere((entry) => entry.id == callbackId);
    _errorCallbacks.removeWhere((entry) => entry.id == callbackId);
    _statusCallbacks.removeWhere((entry) => entry.id == callbackId);
  }

  // 检查麦克风权限
  Future<bool> checkMicrophonePermission(BuildContext? context) async {
    final microphoneStatus = await Permission.microphone.status;
    if (!microphoneStatus.isGranted) {
      debugPrint('麦克风权限未授予');

      // 请求权限
      final status = await Permission.microphone.request();
      if (!status.isGranted) {
        if (context != null) {
          _notifyError('需要麦克风权限才能录音');
          if (context.mounted) {
            UiHelper.showErrorMessage(context, '需要麦克风权限才能录音');
          }
        }
        return false;
      }
    }
    return true;
  }

  // 开始录音
  Future<bool> startRecording(BuildContext? context) async {
    if (_status == RecordingStatus.recording) {
      return true; // 已经在录音中
    }

    // 检查麦克风权限
    final hasPermission = await checkMicrophonePermission(context);
    if (!hasPermission) {
      _updateStatus(RecordingStatus.error);
      return false;
    }

    try {
      debugPrint('开始录音流...');

      // 开始流式录音
      final stream = await _audioRecorder.startStream(
        const RecordConfig(
          encoder: AudioEncoder.pcm16bits,
          sampleRate: 16000,
          numChannels: 1,
          androidConfig: AndroidRecordConfig(
            audioSource: AndroidAudioSource.mic,
          ),
          iosConfig: IosRecordConfig(
            categoryOptions: [
              IosAudioCategoryOption.defaultToSpeaker,
              IosAudioCategoryOption.allowBluetooth,
              IosAudioCategoryOption.allowBluetoothA2DP,
              IosAudioCategoryOption.allowAirPlay,
              IosAudioCategoryOption.allowBluetoothA2DP,
            ],
          ),
          echoCancel: true, // 启用回声消除，避免录制播放的声音
          noiseSuppress: true, // 启用噪音抑制
          autoGain: true, // 自动增益控制，优化麦克风输入
        ),
      );
      debugPrint('录音流已启动: PCM16bits, 采样率=16000Hz, 单声道, 回声消除: 开启, 噪音抑制: 开启');

      // 更新状态
      _updateStatus(RecordingStatus.recording);

      // 监听音频流并通过回调发送
      _audioStreamSubscription = stream.listen((data) {
        if (_status == RecordingStatus.recording) {
          _notifyAudioData(data);
        }
      });

      debugPrint('音频数据流监听已建立');
      return true;
    } catch (e) {
      debugPrint('开始录音失败: $e');
      _notifyError('开始录音失败: $e');
      if (context != null && context.mounted) {
        UiHelper.showErrorMessage(context, '开始录音失败: $e');
      }
      _updateStatus(RecordingStatus.error);
      return false;
    }
  }

  // 停止录音
  Future<bool> stopRecording() async {
    if (_status != RecordingStatus.recording) {
      return true; // 没有在录音
    }

    debugPrint('停止录音...');
    try {
      // 取消音频流订阅
      await _audioStreamSubscription?.cancel();
      _audioStreamSubscription = null;
      debugPrint('音频流订阅已取消');

      // 停止录音
      await _audioRecorder.stop();
      debugPrint('录音已停止');

      // 更新状态
      _updateStatus(RecordingStatus.idle);
      return true;
    } catch (e) {
      debugPrint('停止录音失败: $e');
      _notifyError('停止录音失败: $e');
      _updateStatus(RecordingStatus.error);
      return false;
    }
  }

  // 通知所有音频数据回调
  void _notifyAudioData(Uint8List data) {
    for (var entry in _audioDataCallbacks) {
      try {
        entry.callback(data);
      } catch (e) {
        debugPrint('音频数据回调异常: $e');
      }
    }
  }

  // 通知所有错误回调
  void _notifyError(String error) {
    for (var entry in _errorCallbacks) {
      try {
        entry.callback(error);
      } catch (e) {
        debugPrint('错误回调异常: $e');
      }
    }
  }

  // 更新状态并触发回调
  void _updateStatus(RecordingStatus newStatus) {
    _status = newStatus;

    // 通知所有状态回调
    for (var entry in _statusCallbacks) {
      try {
        entry.callback(newStatus);
      } catch (e) {
        debugPrint('状态回调异常: $e');
      }
    }
  }

  // 释放资源
  Future<void> dispose() async {
    await stopRecording();
    await _audioStreamSubscription?.cancel();
    await _audioRecorder.dispose();
  }
}
